#pragma once

#include <functional>
#include "PtrHash.hpp"
#include "PtrDeepEqual.hpp"
#include "EndAwareIterator.hpp"


namespace terms {
	namespace util {
		/**
		 * \brief Lightweight wrapper around an iterator that preserves the past-the-end indication
		 * without having to keep a reference to the original collection.
		 **/
		template <class Iter>
		class EndAwareIterator
			: public std::pair<bool, Iter>
		{	
		public:
			template <class I>
			EndAwareIterator(I &iter, bool at_end)
				: std::pair<bool, Iter>(!at_end, iter)
			{
			}

		public:
			template <class C, class I>
			EndAwareIterator(const C &container, const I &iter)
				: std::pair<bool, Iter>((iter != container.end()), iter)
			{
			}

		public:
			operator Iter &()
			{
				return get();
			}

		public:
			/**
			 * \brief Return the encapsulated iterator.
			 **/
			Iter &
			get()
			{
				return std::get<1>(*this);
			}
			
		public:
			/**
			 * \returns \c true if this iterator is not past-the-end, i.e.
			 * if dereferencing the iterator should yield a valid
			 * object.
			 **/
			operator bool() const
			{
				return std::get<0>(*this);
			}
		};
	}
}	
